const { getLPCfromEPC, Log } = require('./utils');

class RFID {
  constructor(config) {
    this.position = config.rfid[0].position;
    this.flightInfoUrl = config.flightInfoUrl;
    this.threshold = config.threshold;
    this.startPlate = config.rfid[0].startPlate;
    this.endPlate = config.rfid[0].endPlate;
    this.reader = null; // 存储单个SICKRFU实例
    this.labels = new Map(); // 存储标签信息
    this.ignLablesTime = new Map(); // 存储标签忽略时间
    this.bottomScanedLabels = new Map(); // 存储已扫描的标签
    this.pointer = 0; // 存储标签指针
    this.ResourceID = config.ResourceID;
    this.ignoreLablelsBoot = true; //启动时过滤标签
    this.log = new Log();
    setTimeout(() => {
      this.ignoreLablelsBoot = false;
      console.log ({
        event: 'IgnoreLablelsEnded',
      })
    }, 30000);
  }

  // 处理RFID数据
  newData(data) {
    const timestamp = Date.now();
    data.forEach(item => {
      const { lable, antennaNo, energyValues } = item;
      if (antennaNo >= 8) {
        // 处理底部扫描的标签
        if (this.bottomScanedLabels.has(lable)) {
          this.bottomScanedLabels[lable] = timestamp;
        } else {
          this.bottomScanedLabels.set(lable, timestamp);
        }
      } else {
        if (this.ignLablesTime.has(lable) || this.ignoreLablelsBoot) {
          // 更新标签读到的时间
          this.ignLablesTime.set(lable, timestamp);
        } else {
          // 更新或创建标签信息
          if (this.labels.has(lable)) {
            const labelInfo = this.labels.get(lable);
            if ((timestamp - labelInfo.lastSeen) > this.threshold.intervalBetweenTwoRead) {
              // 距离上次读到超过1秒，认为是新的开始
              labelInfo.firstSeen = timestamp;
            }
            labelInfo.lastSeen = timestamp;
            labelInfo.lastSeenPointer = this.pointer;
          } else {
            // 首次检测到标签
            const { success, bid, jfd } = getLPCfromEPC(lable);
            // 获取今天是一年的第几天
            const today = new Date();
            const dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / 86400000);
            const labelInfo = {
              pointer: this.pointer,
              status: "NEW",
              startPlate: -1,
              endPlate: -1,
              CreateTime: timestamp,
              firstSeen: timestamp,
              lastSeen: timestamp,
              lastSeenPointer: this.pointer,
              baggageInfoObj: null, // 存储航班信息
              lpc: bid,
              valid: jfd == dayOfYear && success
              // antennaHistory: [{
              //   antennaNo,
              //   timestamp,
              //   position,
              //   energy: energyValues ? [...energyValues] : null // 记录完整的能量值数组
              // }]
            };
            this.labels.set(lable, labelInfo);
            
            // 如果配置了航班信息URL，则发起请求
            if (this.flightInfoUrl && bid !=='') {
              this.requestFlightInfo(bid, labelInfo);
            }
          }
        }

      }

    });
  }
  newpointer(pointer){
    this.pointer = pointer;
    const timestamp = Date.now();
    if (pointer === 0) {
      this.ignLablesTime.forEach((time, lable) => {
        // 删除长时间没有读到的标签
        if (timestamp - time > this.threshold.lablesLifeTimeSecs * 1000) {
          this.ignLablesTime.delete(lable);
        }
      });
    }
    this.labels.forEach((labelInfo, lable) => {
      const time = timestamp - labelInfo.lastSeen;
      const setIgnore = () => {
        if (this.ignoreLablelsBoot) return true;
        // 超过100秒没有读到
        // if (time > 1000*100) return true;
        // 连续读到超过一定时间，认为被取下来放在转盘边上了
        if ((labelInfo.lastSeen - labelInfo.firstSeen) > this.threshold.timeasStillSecs * 1000 ) return true;
        // 标签到达上次读到的最后面位置而且没有读到，认为被取下来了
        if (labelInfo.lastSeenPointer === this.pointer && !this.scanning(lable))  return true;
        return false;
      }
      if (setIgnore()) {
        if (!this.ignLablesTime.has(lable)) {
          this.log.add(`IgnoredLable: ${lable}`);
        }
        this.ignLablesTime.set(lable, timestamp);
        this.labels.delete(lable);
      }
    });
  }
  // 请求航班信息
  async requestFlightInfo(lable, labelInfo) {
    try {
      const url = new URL(this.flightInfoUrl);
      url.searchParams.append('key', lable);
      
      const response = await fetch(url.toString(), {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json'
        }
      });
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      
      const baggageInfoObj = await response.json();
      if (!this.ResourceID ||
          !baggageInfoObj.ResourceID ||
          this.ResourceID === baggageInfoObj.ResourceID) {
            labelInfo.baggageInfoObj = baggageInfoObj;
            labelInfo.baggageInfoObj.lpc = lable;
            this.log.add(`GotBaggageInfoObj:${lable}:{baggageInfoObj.flight}`);
      } else {
        this.log.add(`GotBaggageInfoObj:${lable}:ResourceID-RFID:${this.ResourceID}-BSM':${baggageInfoObj.ResourceID}`);
      }
    } catch (error) {
      this.log.add(`Error to get flight info ${lable}: ${error.message}`);
    }
  }

  scanning(lable) { // 默认阈值5秒
    const labelInfo = this.labels.get(lable);
    if (!labelInfo) return false;
    
    const currentTime = Date.now();
    return (currentTime - labelInfo.lastSeen) <= this.threshold.scanningTimeMS;
  }
}
module.exports = RFID;
